package 反射.反射开始;

import 反射.Fs;

/**
 * 疑问1:通过直接new的方式或反射的方式都可以调用公共的结构，开发中到底用那个?
 * 建议:直接new的方式。
 * 什么时候会使用:反射的方式。反射的特征: 动态性
 * 疑问2:反射机制与面向对象中的封装性是不是矛盾的?如何看待两个技术?
 * 不是矛盾的 封装性表示的时不建议你调用私有的 他给你的更好     而反射可以调
 */

/**
 * 关于java.lang.Class类的理解
 * 1.类的加载过程：
 *   程序经过javac.exe命令以后，会生成一个或多个字节码文件(.class结尾)。
 *   接着我们使用java.exe命令对某个字节码文件进行解释运行。相当于将某个字节码文件
 *   加载到内存中。此过程就称为类的加载。加载到内存中的类，我们就称为运行时类，此
 *   运行时类，就作为Class的一个实例。
 * 2.换句话说，Class的实例就对应着一个运行时类。
 * 3.加载到内存中的运行时类，会缓存一定的时间。在此时间之内，
 *    我们可以通过不同的方式来获取此运行时类。
 */

public class 根据具体的包的位置创建Class {
    public static void main(String[] args) {
        获取方式();
    }
    private static void 获取方式() {
        Class<Fs> fsClass = Fs.class;//获得class实例的方式
        System.out.println(fsClass);//class 反射.Fs

        Fs fs = new Fs();//通过运行时类的对象，调用getClass()
//        Class<Fs> aClass = (Class<Fs>) fs.getClass();//获得class实例的方式
        Class<? extends Fs> aClass = fs.getClass();//获得class实例的方式
        System.out.println(aClass);//class 反射.Fs

        //:调用CLass的静态方法: forName(String classPath)
        Class<?> aClass1 = null;
        try {
            aClass1 = Class.forName("反射.Fs");//最能体现反射动态性
            System.out.println(aClass1);//class 反射.Fs
        } catch (ClassNotFoundException e) {e.printStackTrace();}

        System.out.println(fsClass==aClass);//true
        System.out.println(fsClass==aClass1);//true

//        使用类加载器
        /**
         * ●加载:将class文件字节码内容加载到内存中，并将这些静态数据转换成方法区的运行时数据结构，
         * 然后生成一个代表这个类的java.lang.Class对象，作为方法区中类数据的访问入口(即引用地址)。
         * 所有需要访问和使用类数据只能通过这个Class对象。 这个加载的过程需要类加载器参与。
         * ●链接:将Java类的二进制代码合并到JVM的运行状态之中的过程。
         * ➢验证:确保加载的类信息符合JVM规范，例如:以cafe开头， 没有安全方面的问题
         * ➢准备:正式为类变量(static)分配内存并设置类变量默认初始值的阶段，这些内存
         * 都将在方法区中进行分配。
         * ➢解析:虚拟机常量池内的符号引用(常量名)替换为直接引用(地址)的过程。
         * ●初始化:
         * ➢执行类构造器<clinit>()方法的过程。类构造器<clinit>()方法是由编译期自动收集类中
         * 所有类变量的赋值动作和静态代码块中的语句合并产生的。(类构造 器是构造类信
         * 息的，不是构造该类对象的构造器)。
         * ➢当初始化一个类的时候，如果发现其父类还没有进行初始化，则需要先触发其父类
         * 的初始化。
         * ➢虚拟机会保证一个类的<clinit>()方法在多线程环境中被正确加锁和同步。
         */
        ClassLoader classLoader = 根据具体的包的位置创建Class.class.getClassLoader();
        Class<?> aClass2 = null;
        try {
            aClass2 = classLoader.loadClass("反射.Fs");
        } catch (ClassNotFoundException e) {e.printStackTrace();}
        System.out.println(aClass2);//class 反射.Fs

        System.out.println(fsClass==aClass2);//true

    }
}
